package game;

import board.BoardUtil;
import board.Tile;
import com.jme3.collision.CollisionResult;
import com.jme3.collision.CollisionResults;
import com.jme3.input.InputManager;
import com.jme3.math.Ray;
import com.jme3.math.Vector2f;
import com.jme3.math.Vector3f;
import com.jme3.renderer.Camera;
import com.jme3.renderer.RenderManager;
import com.jme3.renderer.ViewPort;
import com.jme3.scene.Node;
import com.jme3.scene.Spatial;
import com.jme3.scene.control.AbstractControl;
import com.jme3.scene.control.Control;
import effect.EffectSpatial;


public class CursorControl extends AbstractControl {
    protected InputManager inputManager;
    protected Camera camera;
    protected Vector2f lastCursorPosition = Vector2f.ZERO;
    protected Vector3f lastCamPosition = Vector3f.ZERO;

    @Deprecated
    protected CursorControl() {}

    public CursorControl(InputManager inputManager, Camera camera) {
        this.inputManager = inputManager;
        this.camera = camera;
    }

    @Override
    protected void controlUpdate(float tpf) {
	if(camOrCursorHasChanged()) {
	    lastCursorPosition = inputManager.getCursorPosition().clone();
	    lastCamPosition = camera.getLocation().clone();

	    Tile targetTile = rayCastFromMouseFirstTile(DataStore.board);
	    if(targetTile != null) {
		if(spatial instanceof EffectSpatial)
		    DataStore.board.moveEffectSpatial((EffectSpatial)spatial, targetTile.getBoardLocation());
		else
		    spatial.setLocalTranslation(BoardUtil.boardToWorld(targetTile.getBoardLocation()));
	    }
	}
    }

    protected Tile rayCastFromMouseFirstTile(Node onNode) {
        CollisionResults results = new CollisionResults();
	Vector2f click2d = DataStore.inputManager.getCursorPosition();
	Vector3f click3d = DataStore.player.getCamera().getWorldCoordinates(new Vector2f(click2d.x, click2d.y), 0f).clone();
	Vector3f dir = DataStore.player.getCamera().getWorldCoordinates(new Vector2f(click2d.x, click2d.y), 1f).subtractLocal(click3d).normalizeLocal();
	Ray ray = new Ray(click3d, dir);
        onNode.collideWith(ray, results);
        for(CollisionResult result : results) {
	    if(result.getGeometry().getParent() instanceof Tile)
		return (Tile)result.getGeometry().getParent();
        }
        return null;
    }

    protected boolean camOrCursorHasChanged() {
	return !lastCursorPosition.equals(inputManager.getCursorPosition()) || !lastCamPosition.equals(camera.getLocation());
    }

    public Control cloneForSpatial(Spatial spatial) {
	CursorControl control = new CursorControl(inputManager, camera);
        spatial.addControl(control);
        //set other properties here
        return control;
    }

    @Override
    protected void controlRender(RenderManager rm, ViewPort vp) {}
}
